#!/usr/bin/env python
# -*- coding: utf-8 -*-

# package  : Inventorius - PyGTK Custom Inventory System
# version  : $Id$
# copyright: Copyright (c) 2010 Bertrand Kintanar <bertrand.kintanar@gmail.com>
# license  : http://opensource.org/licenses/gpl-3.0.html
# url      : http://c0dejunk1e.tumblr.com/
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# If you find any bugs or have any suggestions email: bertrand.kintanar@gmail.com
#
# Inventorius needs the following to function properly:
#   python >= 2.5.1, gtk >= 2.14.1, pygtk >= 2.12.2, 
#   sqlite >= 2.3.5, sqlalchemy >= 0.5.0

__version__ = "$Rev$"
# $HeadURL$

import sys
import shutil
from os import mkdir, system
from os.path import dirname, split, exists, join, isdir, isfile
import zipfile

BASE_DIR = dirname(__file__)
OUT_DIR  = join(BASE_DIR, "dist")
B_DIR    = join(BASE_DIR, "build")
GTK_ZIP  = join("tools", "windows", "gtk", "gtk_to_copy.zip")
INNO_SCRIPT = join("tools", "config-inno.iss")
INNO_EXECUTABLE = '"c:\\Program Files\\Inno Setup 5\\ISCC.exe"'

def _mkdir(newdir):
    """works the way a good mkdir should :)
        - already exists, silently complete
        - regular file in the way, raise an exception
        - parent directory(ies) does not exist, make them as well
    """
    if isdir(newdir):
        pass
    elif isfile(newdir):
        raise OSError("a file with the same name as the desired " \
                      "dir, '%s', already exists." % newdir)
    else:
        head, tail = split(newdir)
        if head and not isdir(head):
            _mkdir(head)
        #print "_mkdir %s" % repr(newdir)
        if tail:
            mkdir(newdir)
            
def path_name(name):
    
    return split(name)[0]


def file_name(name):

    return split(name)[1]

def file_names(names):
    
    return (name for name in names if file_name(name))

def path_names(names):

    return (name for name in names if path_name(name) and not file_name(name))
    
    
class unzip:
    def __init__(self, verbose = False, percent = 10):
        self.verbose = verbose
        self.percent = percent
        
    def extract(self, file, dir):
        if not dir.endswith(':') and not exists(dir):
            _mkdir(dir)

        zf = zipfile.ZipFile(file)

        # create directory structure to house files
        self._createstructure(file, dir)

        num_files = len(zf.namelist())
        percent = self.percent
        divisions = 100 / percent
        perc = int(num_files / divisions)

        # extract files to directory structure
        for i, name in enumerate(zf.namelist()):

            if self.verbose == True:
                print "Extracting %s" % name
            elif perc > 0 and (i % perc) == 0 and i > 0:
                complete = int (i / perc) * percent
                print "%s%% complete" % complete

            if not name.endswith('/'):
                outfile = open(join(dir, name), 'wb')
                outfile.write(zf.read(name))
                outfile.flush()
                outfile.close()


    def _createstructure(self, file, dir):
        self._makedirs(self._listdirs(file), dir)


    def _makedirs(self, directories, basedir):
        """ Create any directories that don't currently exist """
        for dir in directories:
            curdir = join(basedir, dir)
            if not exists(curdir):
                _mkdir(curdir)

    def _listdirs(self, file):
        """ Grabs all the directories in the zip structure
        This is necessary to create the structure before trying
        to extract the file to it. """
        zf = zipfile.ZipFile(file)

        dirs = []

        for name in zf.namelist():
            if name.endswith('/'):
                dirs.append(name)

        dirs.sort()
        return dirs
        
def delete_old_out_dir():

    if exists(OUT_DIR):
    
        shutil.rmtree(OUT_DIR)
        
    if exists(B_DIR):
    
        shutil.rmtree(B_DIR)


def run_py2exe():

    # A hack really, but remember setup.py will run on import
    sys.argv.append("py2exe")
    import setup


def unzip_gtk():
    
    u = unzip()
    u.extract(GTK_ZIP, OUT_DIR)


def run_inno():

    system(INNO_EXECUTABLE + " " + INNO_SCRIPT)


def main():

    #Clean any mess we previously made
    #delete_old_out_dir()
    # run py2exe
    run_py2exe()
    # put the GTK data files in the dist directory
    unzip_gtk()
    # build the single file installer
    run_inno()
    # prevent the windows command prompt from just closing
    raw_input("Done...")

if __name__ == "__main__":
    
    main()
